package com.icloud.common.web.util;

import com.google.common.collect.ImmutableList;
import lombok.extern.slf4j.Slf4j;
import org.bitcoinj.crypto.*;
import org.bitcoinj.wallet.DeterministicSeed;
import org.web3j.crypto.ECKeyPair;
import org.web3j.crypto.Keys;

import java.security.SecureRandom;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 *
 * 生成随机钱包工具类
 *
 * @ClassName: WalletGeneratorUtils
 * @Author: qian951@163.com
 * @Description:
 * @Date: 2023/2/8 10:24
 */
@Slf4j
public class AcctGeneratorUtil {
    public final static String ADDRESS_KEY = "address";
    public final static String PRIVATE_KEY = "privateKey";
    public final static String MNEMONIC_KEY = "mnemonics";

    private final static ImmutableList<ChildNumber> BIP44_ETH_ACCOUNT_ZERO_PATH =
            ImmutableList.of(new ChildNumber(44, true), new ChildNumber(60, true),
                    ChildNumber.ZERO_HARDENED, ChildNumber.ZERO);

    /**
     * 生成随机钱包地址
     * @return
     * @throws MnemonicException.MnemonicLengthException
     */
    public static Map<String,String> generateRandomWallet() throws MnemonicException.MnemonicLengthException {
        long longstartTime = System.currentTimeMillis();
        SecureRandom secureRandom = new SecureRandom();
        byte[] entropy = new byte[DeterministicSeed.DEFAULT_SEED_ENTROPY_BITS / 8];
        secureRandom.nextBytes(entropy);

        //生成12位助记词
        List<String> mnemonicList = MnemonicCode.INSTANCE.toMnemonic(entropy);
        String mnemonics = mnemonicList.stream().collect(Collectors.joining(","));

        //使用助记词生成钱包种子
        byte[] seed = MnemonicCode.toSeed(mnemonicList, "");
        DeterministicKey masterPrivateKey = HDKeyDerivation.createMasterPrivateKey(seed);
        DeterministicHierarchy deterministicHierarchy = new DeterministicHierarchy(masterPrivateKey);
        DeterministicKey deterministicKey = deterministicHierarchy
                .deriveChild(BIP44_ETH_ACCOUNT_ZERO_PATH, false, true, new ChildNumber(0));
        byte[] bytes = deterministicKey.getPrivKeyBytes();
        ECKeyPair keyPair = ECKeyPair.create(bytes);
        //通过公钥生成钱包地址
        String address = Keys.getAddress(keyPair.getPublicKey());

        long endTime = System.currentTimeMillis();
        Map<String, String> result = new HashMap(4);
        result.put(ADDRESS_KEY, "0x"+address);
        result.put(PRIVATE_KEY, keyPair.getPrivateKey().toString(16));
        result.put(MNEMONIC_KEY, mnemonics);
        return result;
    }

}
